#ifndef B2D_ITEXTURE_H
#define B2D_ITEXTURE_H

#include "IGraphicsResource.h"
#include "BaseResource.h"
#include "GraphicEnums.h"

NS_B2D_BEGIN

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief	Texture units.
/// 		Contains the available texture units and their names
////////////////////////////////////////////////////////////////////////////////////////////////////
struct B2D_API TextureUnit
{
	enum Unit
	{
		TEXTURE0,	TEXTURE_DIFFUSE = TEXTURE0,
		TEXTURE1,	TEXTURE_NORMAL	= TEXTURE1,
		TEXTURE2,	TEXTURE_DEPTH	= TEXTURE2,
		TEXTURE3,	TEXTURE_GLOSS	= TEXTURE3
	};

	enum { MAX = 4 };
	static const char* Names[];
};


////////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief	Sampler state for a texture.
////////////////////////////////////////////////////////////////////////////////////////////////////
struct B2D_API SamplerState
{
	TextureFilter	minFilter;
	TextureFilter	magFilter;
	TextureFilter	mipFilter;
	TextureWrap		wrapU;
	TextureWrap		wrapV;

	SamplerState(void)
		: minFilter(TextureFilter::NEAREST), magFilter(TextureFilter::NEAREST), mipFilter(TextureFilter::NEAREST)
		, wrapU(TextureWrap::REPEAT), wrapV(TextureWrap::REPEAT)
	{ }
};

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief	Common base class for all textures.
////////////////////////////////////////////////////////////////////////////////////////////////////
class B2D_API ITexture
	: public IGraphicsResource
	, public BaseResource
{
	B2D_RESOURCE
	B2D_INTERFACE(ITexture)

private:
	static bool generateMipmapsDefault;

public:
	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief	Query if mipmaps are generated by default.
	///
	/// \return	true if it does, false if otherwise.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	static bool generatesMipmapsDefault(void) { return generateMipmapsDefault; }
	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief	Sets the default value for wether mipmaps should be generated or not.
	///
	/// \param	g	true to generate mipmaps by default.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	static void generatesMipmapsDefault(bool g) { generateMipmapsDefault = g; }

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief	Gets the texture format.
	///
	/// \return	The format.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	virtual TextureFormat getFormat(void) const = 0;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief	Query if this texture is initialised.
	///
	/// \return	true if initialised, false if not.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	virtual bool isInitialised(void) const = 0;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief	Gets the width.
	///
	/// \return	The width.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	virtual size_t getWidth(void) const = 0;
	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief	Gets the height.
	///
	/// \return	The height.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	virtual size_t getHeight(void) const = 0;
	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief	Gets the border thickness.
	///
	/// \return	The border.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	virtual int getBorder(void) const = 0;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief	Query if this texture has mipmaps.
	///
	/// \return	true if contains mipmaps, false if not.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	virtual bool hasMipmaps(void) const = 0;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief	Query if this texture supports an alpha channel.
	///
	/// \return	true if contains alpha, false if not.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	virtual bool hasAlpha(void) const = 0;
	/*
	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief	Gets sampler state.
	///
	/// \return	The sampler state.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	virtual const SamplerState& getSamplerState(void) const = 0;
	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief	Sets sampler state.
	///
	/// \param	s	The sampler state.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	virtual void setSamplerState(const SamplerState& s) = 0;
	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief	Query if this sampler is out of data.
	///
	/// \return	true if sampler state dirty, false if not.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	virtual bool isSamplerStateDirty(void) const = 0;
	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief	Updates the sampler state.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	virtual void updateSamplerState(void) = 0;
	*/

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief	Initialise with pixel data.
	///
	/// \param	data   	The data.
	/// \param	width  	The width.
	/// \param	height 	The height.
	/// \param	format 	Describes the format to use.
	/// \param	mipmaps	true to generate mipmaps.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	virtual void initialiseWithData(const void* data, size_t width, size_t height, TextureFormat format, bool mipmaps) = 0;
};
typedef std::shared_ptr<ITexture> TexturePtr;

NS_B2D_END

#endif